#include "visualize.hh"
#include "SDL2/SDL.h"
#include <iostream>
using namespace std;
using namespace cppn;

HypercubeWindow::HypercubeWindow (int w, int h, CPPN* cppn)
: cppn(cppn), window(nullptr), renderer(nullptr), x(0), y(0),
  width(w), height(h)     
 {

    if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
        cerr << "SDL_Init Error: " << SDL_GetError() << '\n';
        return;
    }

   
}

HypercubeWindow::~HypercubeWindow() {

    if (renderer != nullptr) {
        SDL_DestroyRenderer(renderer);
    }

    if (window != nullptr) {
        SDL_DestroyWindow(window);
    }

    SDL_Quit();
}

void
HypercubeWindow::set_source (float x, float y) {
    this->x = x;
    this->y = y;
}

void
HypercubeWindow::show () {
    if (window == nullptr) {
        window = SDL_CreateWindow("CPPN Hypercube", 100, 100, width, height, SDL_WINDOW_SHOWN);
        if (window == nullptr) {
            cerr << "SDL_CreateWindow Error: " << SDL_GetError() << '\n';
            return;
        }
    }

    if (renderer == nullptr) {
        renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
        if (renderer == nullptr) return;
    }
}

void
HypercubeWindow::render() {
    if (window == nullptr || renderer == nullptr) show();

    SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
    SDL_RenderClear(renderer);

    for (int w = 0; w < width; ++w) {
        for (int h = 0; h < height; ++h) {
            const float target_x = 2*w / float(width) - 1;
            const float target_y = 2*h / float(height) - 1;

            cppn->reset();
            cppn->set_input(x, y, target_x, target_y);
            /*const int value = 255 * (1 + cppn->get_weight()) / 2.0f;
            const bool leo = true;//cppn->get_leo();*/
            const float weight = cppn->get_weight();
                const int value = 100 * abs(weight);
                const bool leo = cppn->get_leo();

                if (weight < 0 && leo) {
                    SDL_SetRenderDrawColor(renderer, value*0.6, 0, value, 255);
                } else if (weight > 0 && leo) {
                    SDL_SetRenderDrawColor(renderer, value*0.6, value, 0, 255);                    
                } else {
                    SDL_SetRenderDrawColor (renderer, value, 0, 0, 255);                    
                }

            SDL_SetRenderDrawColor (renderer, value, leo ? value : 0, leo ? value : 0, 255);

            SDL_RenderDrawPoint (renderer, w, h);
            
        }
    }
    SDL_RenderPresent(renderer);
}

void
HypercubeWindow::wait(long ms) {
    SDL_Delay(ms);
}

bool
HypercubeWindow::scroll(float dx, float dy) {
    float tmpx = x; float tmpy = y;

    x += dx;
    y += dy;

    if (x > 1) x = 1; else if (x < -1) x = -1;
    if (y > 1) y = 1; else if (y < -1) y = -1;

    if (x == tmpx && y == tmpy) return false;
    return true;
}

















